﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.CounterManager;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.Preferences;
using ApplicationLibrary.RicherTextBox;
using ApplicationLibrary.SqlConnector;
using Plumber.Masters.ModuleData;
using Plumber.Sales.ModuleData;
using Plumber.Sales.Reports;
using Plumber.Sales.Preferences;
using Plumber.Sales.Reports.DataSet;

namespace Plumber.Sales.Forms
{
    public partial class SalesInvoice : DocumentForm
    {
        private const string PRINT_INVOICE = "PRINT_INVOICE";
        private const string PrintInvoiceLogo = "PRINT_INVOICE_LOGO";
        private const string PrintInvoiceNologo = "PRINT_INVOICE_NOLOGO";
        private const string PRINT_ENVELOPE = "PRINT_ENVELOPE";
        private ComboBoxManager _templateManager = null;
        private DRTemplatesByInvoice _drTemplatesByInvoice = null;
        private ListBoxManager<string> _sentenceManager = null;
        private DRMasterType _drMasterType = null;
        protected DRMasters DrMaster = null;
        private DRTemplates _drTemplates = null;
        private RRSentences _rrSentence = null;
        private DRTitle _drTitle = null;
        private RRTaxCode _rRTaxCode = null;
        private DRTaxCode _dRTaxCode = null;
        private PreferencesManager<NHUnspellPref> _myLanguage = null;
        private NHUnspellPref _nhUnspellPref = null;
        private DRMasterTypeByType _dRMasterTypeByType;
        private ComboBoxManager _cbbManager;
        private ComboBoxManager _cbbTaxCodeManager = null;
        private ComboBoxManager _cbbRestraintManager = null;
        private CounterFormatter _formatter = new CounterFormatter();
        private SalesPref _salesPref;

        private MasterTypes _masterType = MasterTypes.E_Other;
        private string _adminType = string.Empty;
        private string _condomType = string.Empty;

        protected BindableOject<double> CreditNoteAmount = new BindableOject<double>();
        protected BindableOject<int> InvoiceType = new BindableOject<int>() { Value = global::InvoiceType.E_InvoiceEm.Int() };
        protected InvoiceType InvType = global::InvoiceType.E_InvoiceEm;

        #region Scrounger Member

        public ApplicationLibrary.ExtendedControls.TabControl MasterTabControl { get { return tabControl1; } }

        public ComboBox CbbType { get { return cbbType; } }

        public ComboBoxManager CbbManager { get { return _cbbManager; } }

        public CounterControl FncSalesNo { get { return fncSalesNo; } }
        public CounterControl FncSalesNoRef { get { return fncSaleNoRef; } }
        public Label Label19 { get { return label19; } }

        public ComboBox CbbTaxCode { get { return cbbTaxCode; } }

        public NumericTextBox1 NtbTotal { get { return ntbTotal; } }

        public NumericTextBox1 NtbRestraint { get { return ntbRestraint; } }

        public NumericTextBox1 NtbTax { get { return ntbTax; } }

        public NumericTextBox1 NtbAmount { get { return ntbAmount; } }

        public NumericTextBox1 NtbAmountPayed { get { return ntbAmountPayed; } }

        public DBCheckBox CkbRestraint { get { return ckbRestraint; } }
        public ComboBox CbbRestraint { get { return cbbRestraint; } }

        public DBCheckBox CkbDeduction { get { return ckbDeduction; } }
        public DBCheckBox CkbBankRestraint { get { return ckbBankRestraint; } }

        public RadarCodesCtrl RdrCode { get { return rdrCode; } }
        public RadarCodesCtrl RdrAdmin { get { return rdrAdmin; } }
        public RadarTextBox RdrTitle { get { return rdrTitle; } }
        public RicherTextBox RtbBody {get { return rtbBody; }}

        public TextBox TxtDescription { get { return txtDescription; } }
        public TextBox TxtAddress {get { return txtAddress; }}
        public TextBox TxtCity { get { return txtCity; } }
        public TextBox TxtCounty { get { return txtCounty; } }
        public MaskedTextBox MtbZip { get { return mtbZip; } }
        public TextBox MtbTaxNo { get { return mtbTaxNo; } }
        public TextBox MtbFiscalCode { get { return mtbFiscalCode; } }

        public CalendarTextBox CtbDate { get { return ctbDate; } }

        public CalendarTextBox CtbPaymentDate { get { return ctbPaymentDate; } }

        public DBCheckBox CkbPayed { get { return ckbPayed; } }

        public CounterFormatter Formatter { get { return _formatter; } }

        public InvoiceType GetInvoiceType { get { return (InvoiceType)InvoiceType.Value; } }

        public string AnagType { get; private set; }
        public string AnagCode { get; private set; }

        #endregion

        public SalesInvoice()
            : base(Properties.Resources.FN_SalesInvoice)
        {
            ReadPreferences();

            InitializeComponent();

            Label19.Visible = false;
            FncSalesNoRef.Visible = false;
        }

        public SalesInvoice(InvoiceType invoicetype)
            : this()
        {
            InvType = invoicetype;
        }

        private void ReadPreferences()
        {
            _myLanguage = new PreferencesManager<NHUnspellPref>(formName, null);
            _nhUnspellPref = _myLanguage.ReadPreference();

            _salesPref = new PreferencesManager<SalesPref>(formName, null).ReadPreference();
        }

        #region Virtual Method

        protected override IRadarParameters GetKeyFromDocument()
        {
            return new RadarSaleInvoicesParam(fncSalesNo.Text);
        }

        protected override void OnAttachData()
        {
            dbManager = new DbmanagerSalesInvoice("SalesInvoice", new RadarSaleInvoices(InvType), this, InvType);
            dbManager.AddMaster(this, PL_SalesInvoices.Name, true);

            RRMasterTypeForInvoice rrMasterType = new RRMasterTypeForInvoice();
            rrMasterType.Find();

            _cbbManager = new ComboBoxManager();
            for (int t = 0; t < rrMasterType.Count; t++)
                if (rrMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType, t) != MasterTypes.E_Administrator)
                    _cbbManager.AddValue(rrMasterType.GetValue<string>(PL_MasterType.Code, t), rrMasterType.GetValue<string>(PL_MasterType.Description, t));
            _cbbManager.AttachTo(cbbType);

            _rRTaxCode = new RRTaxCode();
            _rRTaxCode.Find();
            _cbbTaxCodeManager = new ComboBoxManager();
            _cbbRestraintManager = new ComboBoxManager();
            _cbbTaxCodeManager.AddValue(string.Empty, string.Empty);
            _cbbRestraintManager.AddValue(string.Empty, string.Empty);
            for (int t = 0; t < _rRTaxCode.Count; t++)
            {
                _cbbTaxCodeManager.AddValue(_rRTaxCode.GetValue<string>(PL_TaxCode.Code, t), _rRTaxCode.GetValue<string>(PL_TaxCode.Description, t));
                _cbbRestraintManager.AddValue(_rRTaxCode.GetValue<string>(PL_TaxCode.Code, t), _rRTaxCode.GetValue<string>(PL_TaxCode.Description, t));
            }
            _cbbTaxCodeManager.AttachTo(cbbTaxCode);
            _cbbRestraintManager.AttachTo(cbbRestraint);

            _dRMasterTypeByType = new DRMasterTypeByType();

            if (_dRMasterTypeByType.Find(MasterTypes.E_Condominium))
            {
                _condomType = _dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);
                rdrCode.AttachCodeType(_condomType);
                rdrCode.RadarForm = new RadarMasterForm(_condomType, RadarMasterForm.Module.Master);
                rdrCode.RadarForm.EnableAddOnFly = true;
                rdrCode.DescriptionControl = txtDescription;
                cbbType.SelectedValue = _condomType;
            }

            if (_dRMasterTypeByType.Find(MasterTypes.E_Administrator))
            {
                _adminType = _dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);
                rdrAdmin.AttachCodeType(_adminType);
                rdrAdmin.RadarForm = new RadarMasterForm(_adminType, RadarMasterForm.Module.Master);
                rdrAdmin.RadarForm.EnableAddOnFly = true;
                rdrAdmin.DescriptionControl = lblAdminDesc;
            }

            switch (InvType)
            {
                case global::InvoiceType.E_InvoiceEm:
                    fncSalesNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SaleInvoices), GlobalInfo.CurrentDate, null);
                    _formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SaleInvoices), GlobalInfo.CurrentDate);
                    fncSaleNoRef.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SaleInvoices), GlobalInfo.CurrentDate, null);
                    break;
                case global::InvoiceType.E_CreditNoteEm:
                    fncSalesNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_CreditNoteEmitted), GlobalInfo.CurrentDate, null);
                    _formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_CreditNoteEmitted), GlobalInfo.CurrentDate);
                    fncSaleNoRef.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SaleInvoices), GlobalInfo.CurrentDate, null);
                    break;
                case global::InvoiceType.E_DebitNoteEm:
                    fncSalesNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_DebitNoteEmitted), GlobalInfo.CurrentDate, null);
                    _formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_DebitNoteEmitted), GlobalInfo.CurrentDate);
                    fncSaleNoRef.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_SaleInvoices), GlobalInfo.CurrentDate, null);
                    break;
            }

            rdrTitle.RadarForm = new RadarTitles();
            rdrTitle.DescriptionControl = lblTitleDesc;

            _templateManager = new ComboBoxManager(cbbTemplates);
            _drTemplatesByInvoice = new DRTemplatesByInvoice(dbManager.DBConnection, false);
            _drTemplates = new DRTemplates(false);
            DrMaster = new DRMasters(false);
            _drTitle = new DRTitle(false);
            _dRTaxCode = new DRTaxCode(false);
            _drMasterType = new DRMasterType(DRMasterType.Module.All);

            _sentenceManager = new ListBoxManager<string>();
            _rrSentence = new RRSentences(false);
            _rrSentence.Find();
            for (int t = 0; t < _rrSentence.Count; t++)
                _sentenceManager.AddValue(_rrSentence.GetValue<string>(PL_Sentences.Text, t), _rrSentence.GetValue<string>(PL_Sentences.Title, t));
            if (_rrSentence.Count > 0)
                _sentenceManager.AttachTo(lsbSentence);
        }

        protected override void OnBindData()
        {
            BindControl(fncSalesNo, PL_SalesInvoices.InvoiceNo, Findable.YES);
            BindControl(fncSaleNoRef, PL_SalesInvoices.InvoiceRef);
            BindControl(ctbDate, PL_SalesInvoices.ReleaseDate);
            BindControl(cbbType, PL_SalesInvoices.Type, "SelectedValue", Findable.YES);
            BindControl(rdrCode, PL_SalesInvoices.Master, Findable.YES);
            BindControl(txtDescription, PL_SalesInvoices.Description);
            BindControl(txtAddress, PL_SalesInvoices.Address);
            BindControl(txtCity, PL_SalesInvoices.City);
            BindControl(mtbZip, PL_SalesInvoices.ZipCode);
            BindControl(txtCounty, PL_SalesInvoices.County);
            BindControl(mtbTaxNo, PL_SalesInvoices.TaxNo);
            BindControl(mtbFiscalCode, PL_SalesInvoices.FiscalCode);
            BindControl(cbbTaxCode, PL_SalesInvoices.TaxCode, "SelectedValue");

            BindControl(rdrTitle, PL_SalesInvoices.Title);

            BindControl(rdrAdmin, PL_SalesInvoices.Administrator, Findable.YES);

            BindControl(rtbBody, PL_SalesInvoices.InvoiceBody, "Rtf");

            BindControl(ntbAmount, PL_SalesInvoices.Amount);
            BindControl(ntbTax, PL_SalesInvoices.Tax);
            BindControl(ntbTotal, PL_SalesInvoices.Total);

            BindControl(ctbPaymentDate, PL_SalesInvoices.PaymentDate);
            BindControl(ckbPayed, PL_SalesInvoices.SalePayed, "DBChecked");
            BindControl(ckbRestraint, PL_SalesInvoices.Restraint, "DBChecked");
            BindControl(cbbRestraint, PL_SalesInvoices.RestraintCode, "SelectedValue");
            BindControl(ntbRestraint, PL_SalesInvoices.RestraintAmount);
            BindControl(ntbAmountPayed, PL_SalesInvoices.AmountPayed);

            BindControl(ntbDeduction, PL_SalesInvoices.DeductionAmount);
            BindControl(ntbBankRestraint, PL_SalesInvoices.BankRestraintAmount);

            BindControl(ckbDeduction, PL_SalesInvoices.Deduction, "DBChecked");
            BindControl(ckbBankRestraint, PL_SalesInvoices.BankRestraint, "DBChecked");

            BindControl(lsbSentence);
            BindControl(cbbTemplates);
            BindControl(btnLoad);

            BindObject(InvoiceType, PL_SalesInvoices.InvoiceType);
            BindObject(CreditNoteAmount, PL_SalesInvoices.CreditNoteAmount);
            BindCounter(fncSalesNo);
        }

        protected override void OnPrepareAuxData()
        {
            rdrAdmin.UpdateDescription();
            rdrTitle.UpdateDescription();

            AnagType = _cbbManager.GetValue<string>();
            AnagCode = rdrCode.Text;
            base.OnPrepareAuxData();
        }

        protected override bool OnBeforeSave()
        {
            CodeMode codeMode = CodeMode.E_CanBeEmpty;
            if (_drMasterType.Find(_cbbManager.GetValue<string>()))
                codeMode = _drMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode);

            if (rdrCode.IsEmpty && codeMode == CodeMode.E_MustExists)
            {
                string mess = string.Format(Properties.Resources.Msg_MissingCode, _drMasterType.GetValue<string>(PL_MasterType.Description, 0));
                MyMessageBox(this, mess,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (ntbAmount.Double == 0)
            {
                MyMessageBox(this, Properties.Resources.Msg_SalesEmptyValue,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (rtbBody.Rtf.Length > 4000)
            {
                MyMessageBox(this, Properties.Resources.Msg_TextTooLenght,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (cbbTaxCode.Text.IsEmpty())
            {
                MyMessageBox(this, Properties.Resources.Msg_TaxCodeEmpty,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }


            if (!ckbPayed.Checked)
                ctbPaymentDate.Text = "";

            return base.OnBeforeSave();
        }

        protected override bool OnAfterAddNew()
        {
            cbbType.SelectedValue = _condomType;
            CreditNoteAmount.Value = 0.0;
            return true;
        }

        protected override void OnAddPreferenceButton(PreferenceForm prefForm)
        {
            prefForm.AddPanel(new PrinterPreferencePanel(formName));
            base.OnAddPreferenceButton(prefForm);
        }

        protected override void OnCustomizeToolbar(ToolStrip toolstrip)
        {
            AddCustomButton("Quotations", Properties.Resources.T_QuotationNo, Properties.Resources.B_Receipt, true);
        }

        protected override void OnCustomButtonClick(ToolStripButton button)
        {
            if (button.Name == "Quotations")
            {
                using (LoadQuotations lq = new LoadQuotations())
                {
                    OpenNewForm(lq, true);
                    if (lq.DialogResult == System.Windows.Forms.DialogResult.OK)
                        LoadQuotation(lq.List);
                }
            }
        }

        private void LoadQuotation(ListView.ListViewItemCollection list)
        {
            foreach (ListViewItem lvi in list)
            {
                if (lvi.Selected)
                {
                    LoadQuotationInSale(lvi.SubItems[0].Text);
                    break;
                }
            }
        }

        private void LoadQuotationInSale(string quotationNo)
        {
            DRQuotations drQuot = new DRQuotations(false);
            if (drQuot.Find(quotationNo))
            {
                cbbType.SelectedValue = drQuot.GetValue<string>(PL_Quotations.Type);
                rdrCode.Text = drQuot.GetValue<string>(PL_Quotations.Master);

                txtAddress.Text = drQuot.GetValue<string>(PL_Quotations.Address);
                txtCity.Text = drQuot.GetValue<string>(PL_Quotations.City);
                txtCounty.Text = drQuot.GetValue<string>(PL_Quotations.County);
                mtbZip.Text = drQuot.GetValue<string>(PL_Quotations.ZipCode);
                mtbTaxNo.Text = drQuot.GetValue<string>(PL_Quotations.TaxNo);
                mtbFiscalCode.Text = drQuot.GetValue<string>(PL_Quotations.FiscalCode);
                rdrAdmin.Text = drQuot.GetValue<string>(PL_Quotations.Administrator);
                rdrTitle.Text = drQuot.GetValue<string>(PL_Quotations.Title);

                rtbBody.Rtf = drQuot.GetValue<string>(PL_Quotations.QuotationBody);

                DrMaster.Find(cbbType.SelectedValue.ToString(), rdrCode.Text);
                cbbRestraint.SelectedValue = DrMaster.GetValue<string>(PL_Masters.RestraintCode);
                cbbTaxCode.SelectedValue = DrMaster.GetValue<string>(PL_Masters.TaxCode);
                ckbRestraint.Checked = DrMaster.GetValue<bool>(PL_Masters.HasRestraint);
            }
        }

        protected override void FocusOnNew()
        {
            fncSalesNo.Focus();
        }

        protected override void OnDisableControlsForEdit()
        {
            fncSalesNo.Enabled = false;
            fncSaleNoRef.Enabled = false;
            rdrAdmin.Enabled = _drMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType) == MasterTypes.E_Condominium;
            btnLoad.Enabled = _templateManager.Count<string>() > 0;
            cbbTemplates.Enabled = _templateManager.Count<string>() > 1;
            ctbPaymentDate.Enabled = ckbPayed.Checked;
            cbbRestraint.Enabled = ckbRestraint.Checked;
            ntbRestraint.Enabled = ckbRestraint.Checked;
        }

        protected override void OnDisableControlsForNew()
        {
            fncSaleNoRef.Enabled = false;
            btnLoad.Enabled = _templateManager.Count<string>() > 0;
            cbbTemplates.Enabled = _templateManager.Count<string>() > 1;
            ctbDate.Today = GlobalInfo.CurrentDate;
            InvoiceType.Value = InvType.Int();
            cbbRestraint.Enabled = ckbRestraint.Checked;
            ntbRestraint.Enabled = ckbRestraint.Checked;
            ctbPaymentDate.Enabled = ckbPayed.Checked;
            cbbType_SelectedIndexChanged(this, EventArgs.Empty);
            base.OnDisableControlsForNew();
        }

        #endregion

        private void cbbType_Validating(object sender, CancelEventArgs e)
        {
            if (dbManager.Status != DBMode.Edit)
                return;

            if (_drMasterType.Find(_cbbManager.GetValue<string>()))
            {
                cbbTaxCode.SelectedValue = _drMasterType.GetValue<string>(PL_MasterType.TaxCode);
                ckbRestraint.Checked = _drMasterType.GetValue<bool>(PL_MasterType.HasRestraint);
                cbbRestraint.SelectedValue = _drMasterType.GetValue<string>(PL_MasterType.RestraintCode);
            }
        }

        private void cbbType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_drMasterType == null || _cbbManager.GetValue<string>() == default(string))
                return;

            CodeMode codeMode = CodeMode.E_MustExists;

            if (_drMasterType.Find(_cbbManager.GetValue<string>()))
            {
                codeMode = _drMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode);
                _masterType = _drMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType);
            }

            if (codeMode == CodeMode.E_IsEmpty)
            {
                rdrCode.Enabled = false;
                rdrCode.DeattachAll();
            }
            else
            {
                rdrCode.ReattachCodeType(_cbbManager.GetValue<string>());
                rdrCode.Enabled = true;
                rdrCode.RadarForm.FilterType = _cbbManager.GetValue<string>();
            }

            rdrAdmin.Visible = lblAdminDesc.Visible = _drMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType) == MasterTypes.E_Condominium;
            if (!rdrAdmin.Visible)
                rdrAdmin.Text = string.Empty;

            RecalculateTotals(false);
            TemplateFiller();
        }

        private void RecalculateTotals(bool calcAmount)
        {
            if (dbManager.Status != DBMode.Edit || cbbTaxCode.SelectedValue == null)
                return;

            Double tax = 0;
            if (_dRTaxCode.Find(cbbTaxCode.SelectedValue.ToString()))
                tax = 1 + _dRTaxCode.GetValue<double>(PL_TaxCode.Percent) / 100;

            if (calcAmount)
                ntbAmount.Double = tax == 0
                                ? ntbTotal.Double
                                : ntbTotal.Double / tax;
            else
                ntbTotal.Double = tax == 0
                ? ntbAmount.Double
                : ntbAmount.Double * tax;

            ntbTax.Double = ntbTotal.Double - ntbAmount.Double;

            double taxRest = 0;
            if (ckbRestraint.Checked && _dRTaxCode.Find(cbbRestraint.SelectedValue.ToString()))
                taxRest = _dRTaxCode.GetValue<double>(PL_TaxCode.Percent) / 100;

            ntbRestraint.Double = ckbRestraint.Checked
                                        ? ntbAmount.Double * taxRest
                                        : 0;
            if (ckbRestraint.Checked)
            {
                ntbTotal.Double = ntbTotal.Double - ntbRestraint.Double;
            }

            if (ckbDeduction.Checked)
            {
                ntbDeduction.Double = Math.Round(ntbTotal.Double / 1.21 * 0.04, 2);
                ntbTotal.Double = ntbTotal.Double - ntbDeduction.Double;
            }

            if (ckbBankRestraint.Checked)
            {
                ntbBankRestraint.Double = Math.Round(ntbTotal.Double / 1.22 * 0.08, 2);
                ntbTotal.Double = ntbTotal.Double - ntbBankRestraint.Double;
            }
        }

        private void TemplateFiller()
        {
            if (_templateManager == null)
                return;

            _templateManager.Clear<string>();
            if (_drTemplatesByInvoice.Find(TemplateType.E_Sale, _cbbManager.GetValue<string>()))
            {
                for (int t = 0; t < _drTemplatesByInvoice.Count; t++)
                {
                    string code = _drTemplatesByInvoice.GetValue<string>(PL_Templates.Code, t);
                    string desc = _drTemplatesByInvoice.GetValue<string>(PL_Templates.Description, t);

                    _templateManager.AddValue(code, desc);
                }
            }
            _templateManager.Refresh();

            if (IsNew && _templateManager.Count<string>() == 1)
                LoadTemplate();

            btnLoad.Enabled = _templateManager.Count<string>() > 0;
            cbbTemplates.Enabled = _templateManager.Count<string>() > 1;
        }

        private void LoadTemplate()
        {
            if (_drTemplates.Find(TemplateType.E_Sale, _templateManager.GetValue<string>()))
                rtbBody.Rtf = _drTemplates.GetValue<string>(PL_Templates.Body);
        }

        private void rdrCode_Validating(object sender, CancelEventArgs e)
        {
            if (string.IsNullOrEmpty(_cbbManager.GetValue<string>()) || rdrCode.IsEmpty)
                return;

            if (DrMaster.Find(_cbbManager.GetValue<string>(), rdrCode.Text))
                LoadDataInInvoice();
        }

        private void LoadDataInInvoice()
        {
            if (dbManager.Status == DBMode.Browse)
                return;
            txtAddress.Text = DrMaster.GetValue<string>(PL_Masters.Address);
            txtCity.Text = DrMaster.GetValue<string>(PL_Masters.City);
            txtCounty.Text = DrMaster.GetValue<string>(PL_Masters.County);
            mtbZip.Text = DrMaster.GetValue<string>(PL_Masters.ZipCode);
            mtbTaxNo.Text = DrMaster.GetValue<string>(PL_Masters.TaxNo);
            mtbFiscalCode.Text = DrMaster.GetValue<string>(PL_Masters.FiscalCode);
            rdrAdmin.Text = DrMaster.GetValue<string>(PL_Masters.Administrator);
            rdrTitle.Text = DrMaster.GetValue<string>(PL_Masters.Title);
            cbbRestraint.SelectedValue = DrMaster.GetValue<string>(PL_Masters.RestraintCode);
            cbbTaxCode.SelectedValue = DrMaster.GetValue<string>(PL_Masters.TaxCode);
            ckbRestraint.Checked = DrMaster.GetValue<bool>(PL_Masters.HasRestraint);

            rdrAdmin.UpdateDescription();
        }

        private void cbbTaxCode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dbManager.Status != DBMode.Edit)
                return;

            RecalculateTotals(false);
        }

        private void ntbAmount_Validated(object sender, EventArgs e)
        {
            RecalculateTotals(false);
        }

        private void ntbTotal_Validated(object sender, EventArgs e)
        {
            RecalculateTotals(true);
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            bool bBodyFill = rtbBody.Text != string.Empty;

            if (!bBodyFill || bBodyFill && MyMessageBox(this, Properties.Resources.Msg_BodyNotEmpty,
            Properties.Resources.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Hand) == System.Windows.Forms.DialogResult.Yes)
                LoadTemplate();
        }

        private void lsbSentence_MouseMove(object sender, MouseEventArgs e)
        {
            int idx = lsbSentence.IndexFromPoint(e.X, e.Y);
            if (idx >= 0 && tltSentence.GetToolTip(lsbSentence) != lsbSentence.Items[idx].ToString())
                tltSentence.SetToolTip(lsbSentence, lsbSentence.Items[idx].ToString());
        }

        private void lsbSentence_MouseDown(object sender, MouseEventArgs e)
        {
            int idx = lsbSentence.IndexFromPoint(e.X, e.Y);
            if (e.Button != MouseButtons.Left)
                idx = -1; ;

            if (idx >= 0)
                DoDragDrop(new DataObject(DataFormats.Rtf, lsbSentence.Items[idx].ToString()), DragDropEffects.Copy);
        }

        private void rtbBody_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.Rtf)
                             ? DragDropEffects.Copy
                             : DragDropEffects.None;
        }

        private void rtbBody_RicherDragOver(object sender, DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.Rtf)
                 ? DragDropEffects.Copy
                 : DragDropEffects.None;
        }

        private int GetCaretIndexFromPoint(RicherTextBox tb, int x, int y)
        {
            Point p = tb.PointToClient(new Point(x, y));
            int i = tb.TextBox.GetCharIndexFromPosition(p);
            if (i == tb.Text.Length - 1)
            {
                Point c = tb.TextBox.GetPositionFromCharIndex(i);
                if (p.X > c.X)
                    i++;
            }
            return i;
        }

        private bool SalesInvoice_OnEnableToolbarSplitButtons(ToolStripSplitButton sender)
        {
            return true;
        }

        protected override void OnAddSplitMenuButton()
        {
            AddSplitPreviewButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_INVOICE_LOGO, PrintInvoiceLogo, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_INVOICE_NOLOGO, PrintInvoiceNologo, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Envelope, Properties.Resources.B_Envelope);

            AddSplitPrintButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_INVOICE_LOGO, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_INVOICE_NOLOGO, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Envelope, Properties.Resources.B_Envelope);
        }

        protected override bool OnPrintDocument(PrintInfo sender, printerForm pf)
        {
            pf.SendEmail += new printerForm.EmailArgsEventHanlder(pf_SendEmail);
            pf.LoadAddress += new printerForm.LoadAddressEventHandler(pf_LoadAddress);
            switch (sender.ReportName)
            {
                case PRINT_INVOICE:
                    return PrintInvoice(pf, true);
                case PrintInvoiceNologo:
                    return PrintInvoice(pf, true);
                case PrintInvoiceLogo:
                    return PrintInvoice(pf, false);
                case PRINT_ENVELOPE:
                    return PrintEnvelope(pf);
                default:
                    return true;
            }
        }

        private void pf_LoadAddress(ApplicationLibrary.Emailer.emailAddress ea)
        {
            Plumber.Masters.Library.EmailAddressLoader emailLoader = new Masters.Library.EmailAddressLoader();
            emailLoader.LoadAddress(ea);
        }

        private void pf_SendEmail(object sender, EmailArgs e)
        {
            printerForm pf = (printerForm)sender;
            pf.ChangeParameterValue("HideLogo", false);
            if (ckbRestraint.Checked)
                pf.ChangeParameterValue("TotalDesc", "TOTALE-RITENUTA");
            else if (ckbDeduction.Checked)
                pf.ChangeParameterValue("TotalDesc", "TOTALE-DETRAZ.");
            e.Attachment = pf.ExportToPdf(fncSalesNo.Text);
            e.Address = GetAddress();
            e.Subject = string.Format(Properties.Resources.Msg_EmittedInvoice, _formatter.ToString(true), ctbDate.Today.ToShortDateString());
        }

        private string GetAddress()
        {
            if (cbbType.SelectedValue.ToString() == _condomType)
                DrMaster.Find(_adminType, rdrCode.Text);
            else
                DrMaster.Find(cbbType.SelectedValue.ToString(), rdrCode.Text);

            return DrMaster.GetValue<string>(PL_Masters.Email);
        }

        private bool PrintInvoice(printerForm pf, bool hidelogo = true)
        {
            DSInvoice dsInvoice = new DSInvoice();
            DSInvoice.InvoiceRow row = dsInvoice.Invoice.NewInvoiceRow();

            pf.Text = Properties.Resources.PRNT_INVOICE;
            string trimmedDesc = txtDescription.Text.TrimEnd(new Char[] { '\r', '\n', '\t', ' ' });

            _formatter.Text = fncSalesNo.Text;
            row.FiscalNo = _formatter.ToString(false);
            string desc = lblTitleDesc.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' });
            desc = desc.SeparConcat(txtDescription.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' }), "\n");
            desc = desc.SeparConcat(txtAddress.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' }), "\n");

            row.Header = string.Concat(desc, "\n", mtbZip.Text, " ", txtCity.Text, " ", txtCounty.Text);
            row.ReleaseDate = ctbDate.Today;

            if (mtbTaxNo.Text == "" || mtbFiscalCode.Text == "")
                row.TaxNo = mtbTaxNo.Text != ""
                    ? mtbTaxNo.Text
                    : mtbFiscalCode.Text;
            else
                row.TaxNo = string.Concat(mtbTaxNo.Text, "\n", mtbFiscalCode.Text);

            if (mtbTaxNo.Text == "" || mtbFiscalCode.Text == "")
                row.TaxNoDesc = mtbTaxNo.Text != ""
                    ? Properties.Resources.T_TaxNo
                    : Properties.Resources.T_FiscalCode;
            else
                row.TaxNoDesc = string.Concat(Properties.Resources.T_TaxNo, "\n", Properties.Resources.T_FiscalCode);

            if (IsNew)
                row.InvoiceBody = rtbBody.Rtf;
            else
            {
                // Questo serve perchè se non vado a browsare sulla seconda pagina, non mi fa il refresh
                row.InvoiceBody = dbManager.GetColumn<string>(PL_SalesInvoices.InvoiceBody, dbManager.Pos);
            }

            if (ckbRestraint.Checked)
            {
                row.RestraintHidden = false;
                row.BodyRestraint = string.Format("Ritenuta 4% ex art. 25 ter. D.p.r 600/1973- su imponibile {0}", ntbAmount.Decimal.ToString("C"));
                row.RestraintAmount = ntbRestraint.Decimal;
            }
            else if (ckbDeduction.Checked)
            {
                row.RestraintHidden = false;
                row.BodyRestraint = string.Format("Detrazione Irpef 36%", ntbAmount.Decimal.ToString("C"));
                row.RestraintAmount = ntbDeduction.Decimal;
            }
            else
                row.RestraintHidden = true;

            row.Amount = ntbAmount.Decimal;
            row.TaxCode = "";
            if (_dRTaxCode.Find(_cbbTaxCodeManager.GetValue<string>()))
                row.TaxCode = _dRTaxCode.GetValue<string>(PL_TaxCode.Description);

            row.Tax = ntbTax.Decimal;
            row.Total = ntbTotal.Decimal + ntbRestraint.Decimal + ntbDeduction.Decimal + ntbBankRestraint.Decimal;

            dsInvoice.Invoice.AddInvoiceRow(row);
            pf.SetParameterValue("HideLogo", hidelogo);
            InvoiceType invType = (InvoiceType)InvoiceType.Value;
            switch (invType)
            {
                case global::InvoiceType.E_InvoiceEm:
                    pf.SetParameterValue("InvoiceType", "FATTURA N°");
                    break;
                case global::InvoiceType.E_DebitNoteEm:
                    pf.SetParameterValue("InvoiceType", "NOTA DI DEBITO N°");
                    break;
                case global::InvoiceType.E_CreditNoteEm:
                    pf.SetParameterValue("InvoiceType", "NOTA DI CREDITO N°");
                    break;
            }
            if (ckbRestraint.Checked)
                pf.SetParameterValue("TotalDesc", "TOTALE-RITENUTA");
            else if (ckbDeduction.Checked)
                pf.SetParameterValue("TotalDesc", "TOTALE-DETRAZIONE");
            else
                pf.SetParameterValue("TotalDesc", "");
            pf.ShowReport(new PrintSales(), dsInvoice);
            return true;
        }

        private bool PrintEnvelope(printerForm pf)
        {
            Plumber.Masters.Library.PrintEnvelope printEnvelope = new Plumber.Masters.Library.PrintEnvelope(pf);

            if (_masterType == MasterTypes.E_Condominium && !string.IsNullOrEmpty(rdrAdmin.Text))
            {
                if (DrMaster.Find(_adminType, rdrAdmin.Text))
                {
                    string titleText = "";
                    if (_drTitle.Find(DrMaster.GetValue<string>(PL_Masters.Title)))
                        titleText = _drTitle.GetValue<string>(PL_Titles.Description);

                    printEnvelope.Print(titleText,
                                        DrMaster.GetValue<string>(PL_Masters.Description),
                                        DrMaster.GetValue<string>(PL_Masters.Address),
                                        DrMaster.GetValue<string>(PL_Masters.ZipCode),
                                        DrMaster.GetValue<string>(PL_Masters.City),
                                        DrMaster.GetValue<string>(PL_Masters.County));
                }
            }
            else
                printEnvelope.Print(lblTitleDesc.Text, txtDescription.Text, txtAddress.Text, mtbZip.Text, txtCity.Text, txtCounty.Text);

            return true;
        }

        private void ckbPayed_CheckStateChanged(object sender, EventArgs e)
        {
            if (ckbPayed.Checked)
                ctbPaymentDate.Today = GlobalInfo.CurrentDate;
            else
                ctbPaymentDate.Text = "";

            ctbPaymentDate.Enabled = ckbPayed.Checked;
        }

        private void ckbRestraint_CheckStateChanged(object sender, EventArgs e)
        {
            if (dbManager.Status == DBMode.Browse)
                return;

            if (ckbRestraint.Checked)
            {
                ckbDeduction.Checked = false;
                ckbBankRestraint.Checked = false;
                ntbDeduction.Double = 0;
                ntbBankRestraint.Double = 0;
            }

            cbbRestraint.Enabled = ckbRestraint.Checked;
            ntbRestraint.Enabled = ckbRestraint.Checked;

            if (_cbbManager.GetValue<string>() != null && DrMaster.Find(_cbbManager.GetValue<string>(), rdrCode.Text))
                cbbRestraint.SelectedValue = ckbRestraint.Checked
                                        ? DrMaster.GetValue<string>(PL_Masters.RestraintCode)
                                        : "";
            RecalculateTotals(false);
        }


        private void ckbDeduction_CheckStateChanged(object sender, EventArgs e)
        {
            if (dbManager.Status == DBMode.Browse)
                return;

            if (ckbDeduction.Checked)
            {
                ckbRestraint.Checked = false;
                ckbBankRestraint.Checked = false;
                ntbBankRestraint.Double = 0;
                ntbRestraint.Double = 0;
            }
            RecalculateTotals(false);
        }

        private void cbbRestraint_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dbManager.Status != DBMode.Edit)
                return;

            RecalculateTotals(false);
        }

        private void rtbTaxCode_Validated(object sender, EventArgs e)
        {
            RecalculateTotals(false);
        }

        protected override bool OnEnableToolbarButtons(ToolStripButton button)
        {
            if (button.Name == "Quotations")
                return dbManager.Status != DBMode.Browse;

            if (button.Name == "tbnDelete" || button.Name == "tbnSave")
                return !(_salesPref.LockSalesPayed && ckbPayed.Checked);

            return base.OnEnableToolbarButtons(button);
        }

        private void ctbDate_Validating(object sender, CancelEventArgs e)
        {
            if (dbManager.Status != DBMode.Browse && IsNew)
            {
                if (ctbDate.Today.Year != GlobalInfo.CurrentDate.Year)
                    MyMessageBox(string.Format(Properties.Resources.Msg_WrongYear, ctbDate.Today.ToShortDateString(), GlobalInfo.CurrentDate.Year),
                        Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void ckbBankRestraint_CheckStateChanged(object sender, EventArgs e)
        {
            if (ckbBankRestraint.Checked)
            {
                ckbDeduction.Checked = false;
                ckbRestraint.Checked = false;
                ntbRestraint.Double = 0;
                ntbDeduction.Double = 0;
            }
            RecalculateTotals(false);
        }

        private void SalesInvoice_Load(object sender, EventArgs e)
        {
        
        }
    }

    //public class DebitNote : SalesInvoice
    //{
    //    public DebitNote()
    //        : base(InvoiceType.E_DebitNoteEm) { }
    //}

    //public class CreditNote : SalesInvoice
    //{
    //    public CreditNote()
    //        : base(InvoiceType.E_CreditNoteEm) { }
    //}

    #region DbManager SalesInvoice

    /// <summary>
    /// Classe derivata per gestioni particolari
    /// </summary>
    ///

    internal class DbmanagerSalesInvoice : DBManager
    {
        private const string JeSlave = "JESLAVE";
        private InvoiceType invType;

        public DbmanagerSalesInvoice(string name, RadarForm radar, DocumentForm document, InvoiceType invType)
            : base(name, radar, document)
        {
            this.invType = invType;
        }

        protected override string CreateMasterQuery()
        {
            this.Table = new PL_SalesInvoices();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(this.Table);
            qB.AddCompare(PL_SalesInvoices.InvoiceNo, "@p1");
            qB.AddCompare(PL_SalesInvoices.InvoiceType, "@p2");
            return qB.Query;
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> pList = new List<SqlABParameter>();

            SqlABParameter sP1 = new SqlABParameter("@p1", PL_SalesInvoices.InvoiceNo);
            sP1.Value = 0;
            pList.Add(sP1);
            SqlABParameter sP2 = new SqlABParameter("@p2", PL_SalesInvoices.InvoiceType);
            sP2.Value = invType.Int();
            pList.Add(sP2);
            return pList;
        }

        protected override void SetParameters(IRadarParameters key, DBCollection collection)
        {
            if (collection.Name == PL_SalesInvoices.Name)
            {
                collection.Parameter[0].Value = key[0];
                collection.Parameter[1].Value = invType.Int();
            }
        }
    }

    #endregion
}